TYT UVL-15W通信协议规范

版本:V3.0 | 修正E5命令,补充完整帧示例

1. 协议概述

1.1 基本特性

1.2 地址空间

读写操作针对对讲机外置SPI Flash的以下绝对地址范围(定义于固件源码):

注意:所有多字节地址、长度均为大端序(Big-Endian)。实际操作时,地址应在此范围内。

2. 协议帧格式

2.1 上位机 -> 对讲机 (请求帧)

[前导0xFE] ... [前导0xFE] 0xEE 0xEF <CMD> <已转义的数据域> <已转义的LRC> 0xFD

核心帧头为3字节固定值FE EE EF。其前必须包含数量≥1的0xFE用于同步与唤醒。

2.2 对讲机 -> 上位机 (响应帧)

[前导0xFE] ... [前导0xFE] 0xEF 0xEE <CMD> <已转义的数据域> <已转义的LRC> 0xFD

核心响应帧头为3字节固定值FE EF EE。其前必须包含数量≥1的0xFE

2.3 帧元素说明

字段长度说明转义要求
请求帧头3字节核心帧头固定为 FE EE EF,其前方为数量≥1的0xFE前导符。不转义
响应帧头3字节核心帧头固定为 FE EF EE,其前方为数量≥1的0xFE前导符。不转义
命令字(CMD)1字节标识操作,见第5节不转义
数据域变长命令参数/数据,格式见第5节需要转义
校验和(LRC)1字节纵向冗余校验值需要转义
帧尾1字节固定 0xFD不转义

3. 字节转义规则

3.1 转义目的

防止数据域及LRC字节在传输过程中与帧控制字符(0xFE, 0xEF, 0xEE, 0xFD)或转义字符(0xFF)冲突。

3.2 发送端转义算法 (上位机编码)

转义范围:仅对数据域LRC的每个原始字节进行转义,命令字不转义。

// 伪代码:对单个原始字节进行转义编码 unsigned char raw_byte; // 原始数据 unsigned char temp = raw_byte + 0x80; // 核心操作:加0x80 if (temp > 0xF9) { // 情况1:需要特殊转义。发送两个字节: 0xFF 后跟 (temp的低4位) 发送字节(0xFF); 发送字节(temp & 0x0F); } else { // 情况2:直接发送结果 发送字节(temp); }

3.3 接收端反转义算法 (对讲机解码,上位机解析响应时使用)

// 伪代码:对接收到的已转义数据域进行反转义 while (有数据待处理) { if (当前字节 != 0xFF) { // 情况1:普通字节。原始字节 = 当前字节 + 0x80 原始字节 = 当前字节 + 0x80; 指针后移1字节; } else { // 情况2:遇到转义序列 0xFF。原始字节 = 0xF0 + 下一个字节 + 0x80 原始字节 = 0xF0 + 下一个字节 + 0x80; 指针后移2字节; // 跳过 0xFF 和随后的低4位字节 } 保存原始字节; }

4. 校验和 (LRC) 计算

4.1 计算规则

4.2 计算示例 (以CMD 0xE0请求为例)

// 原始数据域: "UVL-15W" 的 ASCII unsigned char raw_data[] = {0x55, 0x56, 0x4C, 0x2D, 0x31, 0x35, 0x57}; // 1. 累加 unsigned char sum = 0x55+0x56+0x4C+0x2D+0x31+0x35+0x57; // = 0x1E1, 取低8位 0xE1 // 2. 取补码 unsigned char lrc = 0x100 - 0xE1; // = 0x1F // 3. 转义LRC: 0x1F + 0x80 = 0x9F (≤0xF9,直接发送) // 4. 转义数据域: 每个原始字节 + 0x80 // 0x55+0x80=0xD5, 0x56+0x80=0xD6, 0x4C+0x80=0xCC, 0x2D+0x80=0xAD, 0x31+0x80=0xB1, 0x35+0x80=0xB5, 0x57+0x80=0xD7 // 因此,帧中发送的LRC字节是 0x9F,已转义数据域为 D5 D6 CC AD B1 B5 D7 // 5. 完整请求帧示例(包含2个前导0xFE): // FE FE EE EF E0 D5 D6 CC AD B1 B5 D7 9F FD

5. 命令详解

5.1 命令总览

命令字功能描述请求数据域(原始)成功响应关键说明
0xE0获取设备信息7字节机型字符串0xE1 + 71B设备信息握手命令,必须发送"UVL-15W"
0xE1设备信息响应71字节设备信息(无)响应0xE0,具体格式见5.2节
0xE2开始读频8字节地址范围"READ START OK"需读权限(Clone_Read_Allow==true)
0xE3开始写频8字节地址范围"WRITE START OK"需写权限(Clone_Write_Allow==true)
0xE4写单条数据6+N字节(地址+长度+数据)0xE6 + "WF OK"+回显地址长度必须在0xE3之后
0xE5读写频完成不同字符串(见5.7节)"Reboot"发送后对讲机会重启
0xE6读单条数据6字节(地址+长度)0xE4 + 回显地址长度 + 数据支持分片传输(若长度>128)
0xE7密码校验9字节(类型+密码)密码对错字符串需密码校验
0xEE通用错误错误描述字符串(无)帧错误、LRC错误、命令错误等,见5.10节

5.2 CMD 0xE0: 获取设备信息

5.3 CMD 0xE1: 设备信息响应(71字节)

响应CMD 0xE0的握手请求。数据域为71字节的原始设备信息,其结构(字节偏移与长度)定义如下:

字节偏移长度字段名说明与取值
07机型字符串"UVL-15W" (ASCII)
71分隔符'_' (0x5F)
81子机型号固定为 0x01
91分隔符'_' (0x5F)
101读频保护标志0x00=允许读,0x01=需密码
111写频保护标志0x00=允许写,0x01=需密码
128软件版本8字节软件版本信息
201分隔符'_' (0x5F)
213图片资源版本号格式: {主, 次, 修订},示例: {0x01, 0x00, 0x00}
2412CPU唯一ID12字节CPU唯一标识符
3616Bootloader机型信息16字节Bootloader存储的机型信息
529硬件版本(解密后)9字节解密后的硬件版本字符串
6120序列号(解密后)20字节解密后的序列号字符串

注意:上位机收到此响应后,应检查字节10和11的读写保护标志,以决定后续流程是否需要进行密码验证(CMD 0xE7)。

5.4 CMD 0xE2: 开始读频

5.5 CMD 0xE3: 开始写频

5.6 CMD 0xE4: 写单条数据

5.7 CMD 0xE5: 读写频完成

5.8 CMD 0xE6: 读单条数据

5.9 CMD 0xE7: 密码校验

5.10 CMD 0xEE: 通用错误响应

当对讲机在解析或处理上位机请求时遇到错误,将以此命令响应。上位机必须妥善处理这些错误,以实现健壮的通信。错误信息字符串(已转义)触发条件如下:

错误信息 (原始ASCII)触发条件上位机处理建议
"Frame Head Error"接收到的数据帧,其核心帧头(FE EE EF)不正确。检查发送的帧头格式,或确认链路是否受到干扰。
"Frame Tail Error"接收到的数据帧,其帧尾字节不是0xFD检查帧结构完整性,或确认数据在传输中是否被截断。
"Frame Length Error"接收到的数据帧总长度过短(<5字节),不构成有效帧。检查发送数据是否完整。
"Frame Lrc Error"接收到的数据帧,其LRC校验失败。检查数据域转义算法和LRC计算算法是否正确。上位机应尝试重发先前未成功的请求。此为常见错误。
"Option Value Error"接收到的命令字(CMD)无法识别,或CMD 0xE8的子功能码无法识别。检查发送的命令字是否正确,或确认电台固件版本是否支持该命令。
重要提示:以上所有错误响应均遵循标准响应帧格式:[前导FE]... FE EF EE EE [已转义的错误信息] [已转义的LRC] FD。上位机在收到CMD 0xEE后,应根据具体的错误信息采取相应的重发机制或错误处理策略。例如,若因"Frame Lrc Error"导致读/写某块数据失败,上位机应重发对应的0xE60xE4命令。

6. 典型通信流程

6.1 完整读频流程

  1. APP -> 电台: 0xE0 ("UVL-15W") // 握手
  2. 电台 -> APP: 0xE1 (设备信息) // 检查读保护标志(字节10)
  3. (若保护) APP -> 电台: 0xE7 (类型0x00 + 读密码) // 验证
  4. APP -> 电台: 0xE2 (起始地址, 结束地址) // 开始读
  5. 电台 -> APP: "READ START OK" // 确认
  6. 循环 {
    • APP -> 电台: 0xE6 (地址, 长度) // 请求读一块
    • 电台 -> APP: 0xE4 (地址, 长度, 数据) // 返回数据 (可能分片)
    } until 所有数据读完
  7. APP -> 电台: 0xE5 ("Read Complete") // 读频完成
  8. 电台 -> APP: "Reboot" // 电台将重启
  9. (电台重启后) APP需重新从步骤1开始连接。

6.2 完整写频流程

  1. APP -> 电台: 0xE0 ("UVL-15W") // 握手
  2. 电台 -> APP: 0xE1 (设备信息) // 检查写保护标志(字节11)
  3. (若保护) APP -> 电台: 0xE7 (类型0x01 + 写密码) // 验证
  4. APP -> 电台: 0xE3 (起始地址, 结束地址) // 开始写
  5. 电台 -> APP: "WRITE START OK" // 确认
  6. 循环 {
    • APP -> 电台: 0xE4 (地址, 长度, 数据) // 发送一块数据 (典型为512字节)
    • 电台 -> APP: 0xE6 ("WF OK"+地址+长度) // 写确认
    } until 所有数据发送完
  7. APP -> 电台: 0xE5 ("Write Complete") // 写频完成
  8. 电台 -> APP: "Reboot" // 电台将重启
  9. (电台重启后) APP需重新从步骤1开始连接。

7. 上位机开发关键点与建议

  1. 帧头同步:请求帧核心帧头为FE EE EF,其前需发送数量≥1的0xFE用于设备唤醒和字节同步。期待响应帧核心帧头为FE EF EE
  2. 转义范围:仅数据域和LRC需要转义(+0x80),命令字不转义。注意0xFF转义序列。
  3. LRC计算仅对数据域原始字节计算补码。建议先用已知正确帧(如CMD 0xE0帧)验证算法。
  4. 地址与长度:使用大端序。操作地址应在 0x8000 (32768) 至 0x21000 (135168) 之间。
  5. 进度计算与操作范围CMD 0xE2CMD 0xE3命令中发送的整个有效地址范围(0x8000-0x21000)用于对讲机识别操作的整体大小,上位机可据此计算并显示进度。
  6. 分片读取:必须实现0xE6 0xE4命令响应分片数据的组装逻辑。根据首包中的长度字段,持续接收后续数据块。
  7. 错误处理与重发必须妥善处理CMD 0xEE错误响应。对于"Frame Lrc Error"等传输错误,上位机应实现相应命令的重发机制,并设置合理的超时与重试次数限制。
  8. 最终重启0xE5命令(读频完成发送"Read Complete",写频完成发送"Write Complete")会导致电台重启,这是正常流程。